var webSocket = require('jjWebSocket');
var protocal = require('protocal');
var utils = require('utils');
var OpType = cc.Enum({//#操作牌的类型，碰牌、杠牌、听牌、胡牌、发一张牌
    Peng : 0,
    Gang : 1,
    Ting : 2,
    Hu : 3,
    Chu : 4,//玩家出牌
    Get : 5,//玩家获得一张牌
    Guo : 6,
});
cc.Class({
    extends: cc.Component,

    properties: {
        // foo: {
        //    default: null,      // The default value will be used only when the component attaching
        //                           to a node for the first time
        //    url: cc.Texture2D,  // optional, default is typeof default
        //    serializable: true, // optional, default is true
        //    visible: true,      // optional, default is true
        //    displayName: 'Foo', // optional
        //    readonly: false,    // optional, default is false
        // },
        // ...
        cardsNode:{
            default:[],
            type : cc.Node
        },
        playersNode:{
            default : [],
            type : cc.Node
        },
        pengBtn:{
            default : null,
            type : cc.Node
        },
        gangBtn:{
            default : null,
            type : cc.Node
        },   
        huBtn:{
            default : null,
            type : cc.Node
        },
        guoBtn:{
            default : null,
            type : cc.Node
        },
        plyaerIDLabel:{
            default : null,
            type : cc.Label
        },
        cdDownLabel:{
            default : null,
            type : cc.Label
        },
        outCardScrollView:{
            default : null,
            type : cc.Node
        },
        cardPre:{
            default : null,
            type : cc.Prefab
        },
        jiugong_bg:{
            default : null,
            type : cc.Sprite
        },
        proBarLeftCard:{
            default : null,
            type : cc.ProgressBar
        },
        tempNode:{
            default : null,
            type : cc.Node
        },
        selectJuNode:{
            default : null,
            type : cc.Node
        },
        resultNode:{
            default : null,
            type : cc.Node
        },
        resPlayerNode:{
            default : [],
            type : cc.Node
        }
    },

    // use this for initialization
    onLoad: function () {
        this.scaleCardBig = 1.2;
        this.lastCardNode = this.cardsNode[8];
        this.lastCardNode.active = false;
        this.isCanOpCard = false;//是否可以操作牌
        this.playerID = 0;
        this.playerCards = [];
        this.pengBtn.active = false;
        this.gangBtn.active = false;
        this.huBtn.active = false;
        this.guoBtn.active = false;
        this.cdDownLabel.string = '0';
        this.cdDownLabel.schedule(this.callbackCD, 1);
        this.outCardScrollView.active = false;
        this.resultNode.active = false;
        this.outCardScrollView.getChildByName('view').getChildByName('content').removeAllChildren();
        this.posOff = 0;//相对于玩家自己的位置偏移
        this.tempNode.active = false;
        Array.prototype.remove = function(num){
            return utils.arrayRemove(this,num);
        };
        Array.prototype.removeAll = function(num){
            utils.arrayRemoveAll(this,num);
        };
        Array.prototype.count = function(num){
            return utils.arrayCount(this,num);
        };


        for (var i = 0; i < this.cardsNode.length; i++) {            
            var cardNode = this.cardsNode[i];
            cardNode.tag = i;
            cardNode.on(cc.Node.EventType.TOUCH_END, this.onCardTouchEnd, this);
        };
        for (var i = 0; i < this.playersNode.length; i++) {
            this.playersNode[i].active = false;
            this.playersNode[i].pos = i;
            this.playersNode[i].getChildByName('curOp').active = false;
        };

        var that = this;
        cc.loader.loadResDir("atlas/table3", cc.SpriteAtlas, function (err, atlas) { 
            that.tableAtlas = atlas[0];
        });

        this.ws = this.getComponent('jjWebSocket');
    },
    onEnable: function () {
        this.node.on(protocal.login+'', this.loginRes, this);
        this.node.on(protocal.deal+'', this.dealRes, this);
        this.node.on(protocal.notifyOperate+'', this.notifyOperate, this);
        this.node.on(protocal.notifyOperateRes+'', this.notifyOperateRes, this);
        this.node.on(protocal.operate+'', this.operateRes, this);
        this.node.on(protocal.notifyUpdateData+'', this.notifyUpdateDataRes, this);
        this.node.on(protocal.enterTable+'', this.enterTableRes, this);
        this.node.on(protocal.tableInfo+'', this.getTableInfoRes, this);
        this.node.on(protocal.notifyInOutTable+'', this.notifyInOutTableRes, this);
        this.node.on(protocal.notifyResult+'', this.notifyResultRes, this);
    },

    onDisable: function () {
        this.node.off(protocal.login+'', this.loginRes, this);
        this.node.off(protocal.deal+'', this.dealRes, this);
        this.node.off(protocal.notifyOperate+'', this.notifyOperate, this);
        this.node.off(protocal.notifyOperateRes+'', this.notifyOperateRes, this);
        this.node.off(protocal.operate+'', this.operateRes, this);
        this.node.off(protocal.notifyUpdateData+'', this.notifyUpdateDataRes, this);
        this.node.off(protocal.enterTable+'', this.enterTableRes, this);
        this.node.off(protocal.tableInfo+'', this.getTableInfoRes, this);
        this.node.off(protocal.notifyInOutTable+'', this.notifyInOutTableRes, this);
        this.node.off(protocal.notifyResult+'', this.notifyResultRes, this);
    },
    callbackCD: function(){
        // 这里的 this 指向 component 即 cdDownLabel
        var cd = Number(this.string);
        if (cd > 0) {
            this.string = (cd -1).toString();
        }else if(0 == cd){
            var gameNode = cc.find("Canvas/game");
            var gameSp = gameNode.getComponent('game');
            gameSp.cancelScaleCards();
            gameSp.unActivePGHBtn();
        };
    },
    loginReq: function(){

    },
    loginRes: function(event){
        var data = event.getUserData(); 
        cc.log('loginRes',data);
        this.playerID = data.playerID;
        this.plyaerIDLabel.string = this.playerID;
    },
    enterTableReq: function(tableSize){
        var msg = {};
        msg.id = protocal.enterTable; 
        msg.tableID = 0;
        msg.tableSize = tableSize;
        var msgStr = JSON.stringify(msg);
        this.ws.sendMsg(msgStr);
    },
    enterTableRes: function(event){
        var data = event.getUserData();
        this.tableID = data.tableID;
        this.posOff = data.pos;
        cc.log("牌桌ID是",this.tableID);

        var msg = {};
        msg.id = protocal.tableInfo; 
        msg.tableID = this.tableID;
        var msgStr = JSON.stringify(msg);
        this.ws.sendMsg(msgStr);
    },
    dealRes: function(event){
        var data = event.getUserData();
        data.lockList = [];
        this.updateUICards(data);
        this.lastCardNode.active = false;
        this.outCardScrollView.getChildByName('view').getChildByName('content').removeAllChildren();
        this.jiugong_bg.spriteFrame = this.tableAtlas.getSpriteFrame('jiugong_bg_3');
        this.resultNode.active = false;
    },
    operateRes: function(event){
        var data = event.getUserData();
        var opType  = data.opType;
        this.cancelScaleCards();
        
        if (opType == OpType.Chu) {
            this.lastCardNode.active = false; 
        }else if (opType == OpType.Peng) {
            this.isCanOpCard = true;
            this.lastCardNode.active = true;
        } else if (opType == OpType.Gang){
            
        }else if(opType == OpType.Hu){
            this.lastCardNode.active = true;
        }
        this.updateUICards(data);
    },
    getTableInfoRes: function(event){
        var data = event.getUserData();
        var players = data.players;
        for(var key in players){
            var player = players[key];
            player.jjType = 1;
            this.updateUIPlayer(player);
        }
    },
    notifyInOutTableRes: function(event){
        var data = event.getUserData();
        this.updateUIPlayer(data);
    },
    notifyOperate: function(event){
        var data = event.getUserData();
        var opType  = data.opType;
        var playerID = data.playerID;
        for (var i = 0; i < this.playersNode.length; i++) {
            var playerNode = this.playersNode[i];
            if (playerNode.playerID == playerID && opType == OpType.Get) {
                playerNode.getChildByName('curOp').active = true;
            }else{
                playerNode.getChildByName('curOp').active = false;
            }
        };
        if (opType == OpType.Get) {
             this.cdDownLabel.string = '15';
        } else{
             this.cdDownLabel.string = '10';
        };
        if (this.playerID != playerID) {
            return;
        };
        this.isCanOpCard = true;
        switch (opType){
            case OpType.Peng:
                this.pengBtn.active = true;
                this.guoBtn.active = true;
                break;
            case OpType.Hu:
                this.huBtn.active = true;
                this.guoBtn.active = true;
                break;
            case OpType.Gang:
                this.gangBtn.active = true;
                this.guoBtn.active = true;
                break;
            case OpType.Get://服务器发了一张牌
                this.onGetOneCard(data);
                break;
        }
    },
    notifyResultRes: function(event){
        var data = event.getUserData();
        this.resultNode.active = true;
        this.resPlayerNode[0].getChildByName('gang0l').active = false;
        this.resPlayerNode[0].getChildByName('gang0d').active = false;
        this.resPlayerNode[0].getChildByName('gang1l').active = false;
        this.resPlayerNode[0].getChildByName('gang1d').active = false;
        var players = data.players;
        var index = 0;
        for(var key in players){
            var player = players[key];
            var playerNode = null;
            if (player.isWin) {
                playerNode = this.resPlayerNode[0];
                playerNode.active =  true;
                playerNode.getChildByName('name').getComponent(cc.Label).string = player.playerID;
                this.updateResultRate(playerNode.getChildByName('rate').getComponent(cc.Label), player.rate);
                var cardArr = player.cardList;//所有的牌
                var lockArr = player.lockList;//碰、杠的牌
                for (var j = 0; j < lockArr.length; j++) {
                    cardArr.remove(lockArr[j]);
                };
                cardArr.sort(function(a,b){
                    return a-b});
                var cardNodeIndex = 0;
                while(lockArr.length > 0){
                    var firstCardNum = lockArr[0];
                    var firstCardCount = lockArr.count(firstCardNum);
                    var opType = (firstCardCount == 3) ? OpType.Peng : OpType.Gang;
                    for (var j = 0; j < 3; j++) {
                        var cardNode = playerNode.getChildByName('card'+cardNodeIndex).getChildByName('card');
                        var cardNum = lockArr[j];
                        cardNode.cardNum = cardNum;
                        this.updateUICard(cardNode,cardNum,null);
                        cardNodeIndex += 1;
                    };
                    lockArr.removeAll(firstCardNum);

                }
                for (var j = 0; j < cardArr.length; j++) {
                    var cardN = playerNode.getChildByName('card'+cardNodeIndex);
                    if (cardN) {
                        var cardNode = cardN.getChildByName('card');
                        if (undefined != cardNode) {
                            var cardNum = cardArr[j];
                            cardNode.cardNum = cardNum;
                            this.updateUICard(cardNode,cardNum,null);
                            cardNodeIndex += 1;
                        }else{
                            cc.log('game.js','更新显示牌失败');
                            cc.log(cardArr,lockArr);
                        }
                    }; 
                };
            }else{
                index += 1;
                playerNode = this.resPlayerNode[index];
                playerNode.active =  true;
                playerNode.getChildByName('name').getComponent(cc.Label).string = player.playerID;
            }
        }
        for(var i=index+1; i <6; i++){
            var playerNode = this.resPlayerNode[i];
            playerNode.active =  false;
        }
    },
    updateResultRate: function(lb,rate){
        var str = '';
        for(var key in rate){
            if (rate[key] != 0) {
                if (key == 'mg') {//明杠
                    str += '  明杠 *'+rate[key];
                }else if(key == 'ag'){//暗杠
                    str += '  暗杠 *'+rate[key];
                }else if(key == 'mq'){//门清
                    str += '  门清 *'+rate[key];
                }else if(key == 'zm'){//自摸
                    str += '  自摸 *'+rate[key];
                }
            };
        }
        lb.string = str;
    },
    addCardToOutScr: function(cardNum){
        this.outCardScrollView.active = true;   
        var contentView = this.outCardScrollView.getChildByName('view').getChildByName('content');
        var newNode = cc.instantiate(this.cardPre);
        newNode.scaleX = 0.8;
        newNode.scaleY = 0.8;
        var span = 8;
        var posY = -6.3;
        var posX = (contentView.childrenCount + 0.5) * newNode.getContentSize().width * newNode.scaleX + contentView.childrenCount * span;
        this.updateUICard(newNode,cardNum);
        newNode.setPosition(posX,posY);
        contentView.addChild(newNode);
        var needWidth = posX+ 0.5*newNode.getContentSize().width*newNode.scaleX;
        if (needWidth > this.outCardScrollView.getContentSize().width) {
            var scrollView = this.outCardScrollView.getComponent(cc.ScrollView)
            newNode.active= false;
            contentView.setContentSize(needWidth,contentView.getContentSize().height);
            scrollView.scheduleOnce(function(dt){
                scrollView.scrollToRight(0.1);
                newNode.active = true;
            }, 0);
        };
    },
    notifyOperateRes: function(event){
        var data = event.getUserData();
        var opType  = data.opType;
        switch (opType){
            case OpType.Chu:
                this.addCardToOutScr(data.cardNum);
                break;
            case OpType.Peng:
                console.log('玩家 '+data.playerID+' 碰了 '+(this.convertCardName(data.cardNum)) ) 
                break;
            case OpType.Hu:
                console.log('玩家 '+data.playerID+' 胡了 '+(this.convertCardName(data.cardNum)) ) 
                this.outCardScrollView.getChildByName('view').getChildByName('content').removeAllChildren();
                this.outCardScrollView.active = false;
                break;
        }
    },
    convertCardName: function(cardNum){
        var cardNumStr = (cardNum%16)+'';
        var cardBgType = Math.floor(cardNum/16);
        switch (cardBgType){
            case 0://条
                return cardNumStr+'条';
            case 1://饼
                return cardNumStr+'饼';
            case 2://万
                return cardNumStr+'万';
            default:
                return '';
        }
    },
    notifyUpdateDataRes: function(event){
        var data = event.getUserData();
        var leftCardNum = data.leftCardNum;
        this.proBarLeftCard.progress = (1-leftCardNum/108.0);
    },
    onGetOneCard: function(data){
        var cardNum = data.cardNum;
        this.updateUICards(data);

        for (var i = 0; i < this.cardsNode.length; i++) {
            var cardNode = this.cardsNode[i];
            if (cardNode.cardNum == cardNum) {
                cardNode.rotation = 0;
                cardNode.scale = this.scaleCardBig;
                break;
            };
        };
        this.lastCardNode.active = true;
    },
    updateUICards: function(data){
        var cardArr = data.cardList;//所有的牌
        var lockArr = data.lockList;//碰、杠的牌
        cc.log(cardArr,lockArr);
        for (var i = 0; i < lockArr.length; i++) {
            cardArr.remove(lockArr[i]);
        };

        console.log('sort pre '+cardArr);
        cardArr.sort(function(a,b){
            return a-b});
        console.log('sort hou '+cardArr);


        var cardNodeIndex = 0;
        while(lockArr.length > 0){
            var firstCardNum = lockArr[0];
            var firstCardCount = lockArr.count(firstCardNum);
            var opType = (firstCardCount == 3) ? OpType.Peng : OpType.Gang;

            for (var i = 0; i < 3; i++) {
                var cardNode = this.cardsNode[cardNodeIndex];
                var cardNum = lockArr[i];
                cardNode.cardNum = cardNum;
                this.updateUICard(cardNode,cardNum,opType);
                cardNodeIndex += 1;
            };
            lockArr.removeAll(firstCardNum);
        }
        if (cardNodeIndex == 3){
            this.jiugong_bg.spriteFrame = this.tableAtlas.getSpriteFrame('jiugong_bg_2');
        }else if(cardNodeIndex == 6){
            this.jiugong_bg.spriteFrame = this.tableAtlas.getSpriteFrame('jiugong_bg_1');
        }
        for (var i = 0; i < cardArr.length; i++) {
            var cardNode = this.cardsNode[cardNodeIndex];
            if (undefined != cardNode) {
                var cardNum = cardArr[i];
                cardNode.cardNum = cardNum;
                this.updateUICard(cardNode,cardNum,null);
                cardNodeIndex += 1;
            }else{
                cc.log('game.js','更新显示牌失败');
                cc.log(cardArr,lockArr);
            }
        };
    },
    updateUICard:function(cardNode,cardNum,opType){
        var num = cardNode.getChildByName('num');
        var bg = cardNode.getChildByName('bg');
        var state = cardNode.getChildByName('state');
        var stateLabel = state.getComponent("cc.Label");
        var spriteNum = num.getComponent(cc.Sprite);
        var spriteBg = bg.getComponent(cc.Sprite);
        var cardBgType = Math.floor(cardNum/16);
        switch (cardBgType){  
            case 0://条
                //spriteBg.spriteFrame = this.tableAtlas.getSpriteFrame('card_bg_tiao');
                spriteNum.spriteFrame = this.tableAtlas.getSpriteFrame('T_0'+(cardNum%16));
                break;
            case 1://饼
                //spriteBg.spriteFrame = this.tableAtlas.getSpriteFrame('card_bg_bing');
                spriteNum.spriteFrame = this.tableAtlas.getSpriteFrame('B_0'+(cardNum%16));
                break;
            case 2://万
                //spriteBg.spriteFrame = this.tableAtlas.getSpriteFrame('card_bg_wan');
                spriteNum.spriteFrame = this.tableAtlas.getSpriteFrame('W_0'+(cardNum%16));
                break;

        }
        cardNode.opType = opType;
        if (opType == OpType.Peng) {
            stateLabel.string = '碰';
        }else if (opType == OpType.Gang) {
            stateLabel.string = '杠';
        }else{
            stateLabel.string = '';
        }
    },
    updateUIPlayer: function(playerData){
        var pos = playerData.pos;
        pos = (pos+6-this.posOff)%6;
        var playerNode = this.playersNode[pos];
        if (playerData.jjType == 1) {
            playerNode.active = true;
        }else{
            playerNode.active = false;
        }
        playerNode.playerID = playerData.playerID;
        playerNode.getChildByName('userID').getComponent(cc.Label).string = playerData.playerID;
    },
    onCardTouchEnd: function(event){
        if (false==this.isCanOpCard) {return};
        console.log('onCardTouchEnd');
        var cardNode = event.currentTarget;
        if (null!=cardNode.opType) {return};
        if (cardNode.scale==this.scaleCardBig) {
            //出牌
            this.isCanOpCard = false;
            var cardNum = cardNode.cardNum;
            var msg = {};
            msg.id = protocal.operate; 
            msg.opType = OpType.Chu;
            msg.cardNum = cardNum;
            var msgStr = JSON.stringify(msg);
            console.log(msgStr);
            this.ws.sendMsg(msgStr);
        } else{
            this.cancelScaleCards();
            cardNode.scale = this.scaleCardBig;
        };
    },
    cancelScaleCards: function(){
        for (var i = 0; i < this.cardsNode.length; i++) {
            var cardNode = this.cardsNode[i];
            cardNode.scale = 1;
            cardNode.rotation = 0;
        };
    },
    unActivePGHBtn: function(){
        this.pengBtn.active = false;
        this.gangBtn.active = false;
        this.huBtn.active = false;
        this.guoBtn.active = false;
    },
    pengEvent: function(event, customEventData){
        this.unActivePGHBtn();
        this.reqOperate(OpType.Peng);
    },
    gangEvent: function(event, customEventData){
        this.unActivePGHBtn();
        this.reqOperate(OpType.Gang);
    },
    huEvent: function(event, customEventData){
        this.unActivePGHBtn();
        this.reqOperate(OpType.Hu);
    },
    guoEvent: function(event, customEventData){
        this.unActivePGHBtn();
        this.reqOperate(OpType.Guo);
    },
    reqOperate: function(opType){
        var msg = {};
        msg.id = protocal.operate; 
        msg.opType = opType;
        var msgStr = JSON.stringify(msg);
        this.ws.sendMsg(msgStr);
    },
    selectJuEvent: function(event,customEventData){
        cc.log(customEventData);
        this.tempNode.active = true;
        this.selectJuNode.active = false;
        this.enterTableReq(Number(customEventData));
    },
    // called every frame, uncomment this function to activate update callback
    // update: function (dt) {

    // },
});
